package ssq.gamest.wolfmankill.port_android;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import net.sf.json.JSONObject;
import ssq.gamest.wolfmankill.Participant.Role;
import ssq.gamest.wolfmankill.Participant.Status;
import ssq.gamest.wolfmankill.R;
import ssq.gamest.wolfmankill.WSClient;
import ssq.gamest.wolfmankill.WSServer;
import ssq.utils.FileUtils;
import ssq.utils.message_quene.Receiver;
import ssq.utils.port_android.UtilsApp;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class MainActivity extends Activity implements Receiver {
  private static final long serialVersionUID = 1L;

  static WSClient client;
  LinkedList<String> names = new LinkedList<String>();
  private LinearLayout playerLinearLayout;
  static MainActivity instance;
  ImageView roleView, sergentView;

  public static Handler handler = new Handler() {
    @Override
    public void handleMessage(Message message) {
      String msg = message.obj.toString();
      client.dispatch(msg);
    }
  };

  private void connect(String addr, String name, int port) {
    try {
      client = new WSClient(new URI("ws://" + addr + ":" + port), name);
      client.connect();

      saveLogin(addr, name, port);
    } catch (URISyntaxException e1) {
      instance.appendMessage("连接的格式不正确 : \n" + e1.getLocalizedMessage());

      clearLogin();

      instance.connect();
    }
  }

  public void info(String info) {
    UtilsApp.alert(info, this);
    appendMessage(info);
  }

  public void appendMessage(String msg) {
    history.append(msg + '\n');

    int offset = history.getMeasuredHeight() - historyScrollView.getMeasuredHeight() + 80;
    if (offset < 0) {
      offset = 0;
    }

    historyScrollView.scrollTo(0, offset);
  }

  public void saveLogin(String addr, String name, int port) {
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    Editor editor = sharedPreferences.edit();
    editor.putString("hostIP", addr).putString("usrname", name).putInt("port", port).commit();
  }

  public void connect() {
    if (client != null && client.isOpen()) {
      client.close();
    }

    if (savedLogin()) {
      SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
      connect(sharedPreferences.getString("hostIP", "localhost"), sharedPreferences.getString("usrname", "无名氏"), sharedPreferences.getInt("port", 444));
    } else {
      LayoutInflater factory = LayoutInflater.from(instance);
      final View textEntryView = factory.inflate(R.layout.dialog, null);
      final EditText addrT = (EditText) textEntryView.findViewById(R.id.addr_et);
      final EditText nameT = (EditText) textEntryView.findViewById(R.id.name_et);
      final EditText portT = (EditText) textEntryView.findViewById(R.id.port_et);
      AlertDialog.Builder builder;

      builder = new AlertDialog.Builder(instance).setTitle("用户登录").setIcon(android.R.drawable.ic_dialog_info).setView(textEntryView).setPositiveButton("登录", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          String name = nameT.getText().toString();
          if (name == null || name.trim().length() == 0) {
            nameT.setText("无名氏");
          }

          connect(new String(addrT.getText().toString()), name, Integer.valueOf(portT.getText().toString()));
        }

      }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          dialog.dismiss();
        }
      });
      builder.create().show();
    }
  }

  public boolean savedLogin() {
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    return sharedPreferences.contains("hostIP") && sharedPreferences.contains("usrname");
  }

  public void queryInfo(String msg) {
    JSONObject jsonObject = JSONObject.fromObject(msg);
    String hint = jsonObject.getString("hint");
    final String backType = jsonObject.getString("backType");

    AlertDialog.Builder builder;
    final EditText editText = new EditText(instance);

    builder = new AlertDialog.Builder(instance).setTitle("上帝问你话~").setMessage(hint).setIcon(android.R.drawable.ic_dialog_info).setView(editText).setPositiveButton("回复", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        String result = editText.getText().toString();

        if (result == null) {
          result = "";
        }

        JSONObject resultJson = new JSONObject();

        resultJson.put("type", backType);
        resultJson.put("msg", result);

        client.send(resultJson.toString());
      }
    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        JSONObject resultJson = new JSONObject();

        resultJson.put("type", backType);
        resultJson.put("msg", "");

        client.send(resultJson.toString());
      }
    });
    builder.create().show();
  }

  OnClickListener voteListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
      Button button = (Button) v;

      if (button.isEnabled() && client.canVote) {
        client.send(WSServer.constructMessage("vote", button.getText().toString().split("<-")[0]));
      }
    }
  };

  private OnLongClickListener chatListener = new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
      if (chatable) {
        Button button = (Button) v;

        sendMessage(button.getText().toString());
      }
      return false;
    }
  };

  private TextView statusLabel;

  private TextView history;
  private ScrollView historyScrollView;
  private ScrollView playerListScrollView;

  private boolean chatable = false;

  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    instance = this;
    iniView();
    enableReconnect();
  }

  private void iniView() {
    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main_activity);

    roleView = (ImageView) findViewById(R.id.roleView);
    sergentView = (ImageView) findViewById(R.id.sergentView);

    Bitmap icon = FileUtils.getImageFromAssetsFile("icons/sergent.png");
    sergentView.setImageBitmap(icon);
    sergentView.setVisibility(View.GONE);

    icon = FileUtils.getImageFromAssetsFile("icons/outsider.png");
    roleView.setImageBitmap(icon);

    playerLinearLayout = (LinearLayout) findViewById(R.id.layout_players);
    playerListScrollView = (ScrollView) findViewById(R.id.scrollView_players);
    historyScrollView = (ScrollView) findViewById(R.id.scrollView_history);
    history = (TextView) findViewById(R.id.history_tv);
    statusLabel = (TextView) findViewById(R.id.status_tv);
  }

  @Override
  public void onBackPressed() {
    if (!chatable) {
      super.onBackPressed();
    }
  }

  public static MainActivity getInstance() {
    return instance;
  }

  private void disableOption() {
    disable("all");
  }

  String constructMsg(String msg, String from, String to) {
    JSONObject tmp = JSONObject.fromObject(WSServer.constructMsg(msg, from));
    tmp.put("to", to);
    return tmp.toString();
  }

  private void sendMessage(final String to) {
    AlertDialog.Builder builder;
    final EditText editText = new EditText(instance);

    builder = new AlertDialog.Builder(instance).setTitle("聊天").setMessage("向" + to + "发送消息").setIcon(android.R.drawable.ic_dialog_info).setView(editText).setPositiveButton("发送", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        String result = editText.getText().toString();

        if (result == null) {
          result = "";
        }

        JSONObject resultJson = new JSONObject();

        resultJson.put("type", "msg");
        resultJson.put("to", to);
        resultJson.put("msg", result);

        client.send(resultJson.toString());
      }
    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
      }
    });
    builder.create().show();
  }

  public void resetPlayers() {
    playerLinearLayout.removeAllViews();
    LayoutParams buttonParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    buttonParams.weight = 1;
    ViewGroup.LayoutParams rowParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

    LinearLayout row = null;
    boolean left = true;
    for (String name : names) {
      if (left) {
        row = new LinearLayout(this);
        row.setOrientation(LinearLayout.HORIZONTAL);
        row.setLayoutParams(rowParams);
      }

      Button button = new Button(this);

      button.setLayoutParams(buttonParams);
      button.setText(name);
      button.setBackgroundColor(Color.WHITE);
      button.setOnClickListener(voteListener);
      button.setOnLongClickListener(chatListener);
      row.addView(button);

      if (left) {
        playerLinearLayout.addView(row);
      }

      left = !left;
    }
  }

  public void refreshState() {
    if (client != null && client.getMe() != null && client.isOpen()) {
      Role myRole = client.getMe().role;
      String roleName = myRole.getEnglishName();
      statusLabel.setText(myRole.toString());

      Bitmap icon = FileUtils.getImageFromAssetsFile("icons/" + roleName + ".png");
      roleView.setImageBitmap(icon);

      statusLabel.setText(client.getMe().name + " " + client.getMe().role + " " + client.getMe().status);

      if (client.getMe().isSergent) {
        sergentView.setVisibility(View.VISIBLE);
        statusLabel.setText(statusLabel.getText().toString() + " 警长");
      } else {
        sergentView.setVisibility(View.GONE);
      }
    } else {
      statusLabel.setText("点击我, 连接到服务器");
    }
  }

  public void reset() {
    client.getMe().forget();
    enableOption();
    names.clear();
    resetPlayers();
    refreshState();
    history.setText("");
  }

  private void enableOption() {
    for (int i = playerLinearLayout.getChildCount() - 1; i >= 0; --i) {
      playerLinearLayout.getChildAt(i).setEnabled(true);
    }

    enableChat();
  }

  public void highlight(String msg) {
    for (int i = playerLinearLayout.getChildCount() - 1; i >= 0; --i) {
      Button button = (Button) ((LinearLayout) playerLinearLayout.getChildAt(i >> 1)).getChildAt(i & 1);
      String name = button.getText().toString().split("<-")[0];
      button.setText(name);
      button.setBackgroundColor(Color.WHITE);
    }

    if (msg != null && !msg.trim().equals("")) {
      List<String> entrys = Arrays.asList(msg.split(","));

      for (String entry : entrys) {
        String[] tmp = entry.split("=");

        for (int i = (playerLinearLayout.getChildCount() << 1) - 1; i >= 0; --i) {
          Button button = (Button) ((LinearLayout) playerLinearLayout.getChildAt(i >> 1)).getChildAt(i & 1);
          if (button == null) {
            continue;
          }

          String name = button.getText().toString().split("<-")[0];

          if (name.equals(tmp[1])) {
            button.setText(name + "<-" + tmp[0]);
            button.setBackgroundColor(Color.YELLOW);
          }
        }
      }
    }
  }

  public void shiver(String msg) {
    Vibrator vibrator = (Vibrator) instance.getSystemService(Context.VIBRATOR_SERVICE);
    vibrator.vibrate(50);

    appendMessage(msg);
  }

  public void disableChat(String msg) {
    chatable = false;
  }

  public void enableChat() {
    chatable = true;
  }

  public void enable(String msg) {
    client.getMe().status = Status.alive;
    refreshState();

    if (msg.equals("all")) {
      enableOption();
    } else {
      for (int i = playerLinearLayout.getChildCount() - 1; i >= 0; --i) {
        Button button = (Button) playerLinearLayout.getChildAt(i);
        if (msg.equals(button.getText().toString())) {
          button.setEnabled(true);
        }
      }
    }
  }

  public void disable(String msg) {
    if (msg.equals("all")) {
      client.getMe().status = Status.dead;
      refreshState();
    } else {
      for (int i = playerLinearLayout.getChildCount() - 1; i >= 0; --i) {
        Button button = (Button) ((LinearLayout) playerLinearLayout.getChildAt(i >> 1)).getChildAt(i & 1);
        if (msg.contains(button.getText())) {
          button.setEnabled(false);
        }
      }
    }
  }

  public String toDetailedString() {
    try {
      StringBuilder sb = new StringBuilder((client == null) ? "" : client.toDetailedString());
      sb.append("\n names: ").append(names.toString());
      return sb.toString();
    } catch (Exception e) {
      return "";
    }
  }

  public void setNames(List<String> asList) {
    names = new LinkedList<String>(asList);
    resetPlayers();
  }

  OnClickListener reconnectListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
      connect();
    }
  };

  public void enableReconnect() {
    refreshState();
    statusLabel.setOnClickListener(reconnectListener);
    playerListScrollView.setOnClickListener(reconnectListener);
    historyScrollView.setOnClickListener(reconnectListener);
  }

  public void disableReconnect() {
    statusLabel.setOnClickListener(null);
    playerListScrollView.setOnClickListener(null);
    historyScrollView.setOnClickListener(null);
  }

  public void clearLogin() {
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    sharedPreferences.edit().clear().commit();
  }

  @Override
  public void consume(JSONObject msg) {
    Message message = new Message();
    message.obj = msg;
    handler.sendMessage(message);
  }
}
